13. ROS Node: drive_bot
ROS Node: drive_bot
This server node provides a
ball_chaser/command_robot
service
to drive the robot around by setting its linear x and angular z velocities. The service server
publishes
messages containing the velocities for the wheel joints.
After writing this node, you will be able to request the
ball_chaser/command_robot
service, either from the terminal or from a client node, to drive the robot by controlling its linear x and angular z velocities.
Reference
The
drive_bot.cpp
node is similar to the
arm_mover.cpp
node that you already wrote. Both nodes contain a ROS
publisher
and
service
. But this time, instead of publishing messages to the arm joint angles, you have to publish messages to the wheels joint angles. Please refer to the
arm_mover.cpp
node before you begin coding the
drive_bot.cpp
node.
ROS Service File
1- Write the
DriveToTarget.srv
file
Create a
DriveToTarget.srv
file under the
srv
directory of
ball_chaser
. Then, define the
DriveToTarget.srv
file as follows:
Request :
-
linear_x
type float64 -
angular_z
type float64
Response :
-
msg_feedback
type string
2- Test
DriveToTarget.srv
After writing the service file, test it with ROS. Open a new terminal and execute the following:
$ cd /home/workspace/catkin_ws/
$ source devel/setup.bash
$ rossrv show DriveToTarget
You should receive this response:
[ball_chaser/DriveToTarget]:
float64 linear_x
float64 angular_z
---
string msg_feedback
drive_bot.cpp
Node
Now it’s time to write the
drive_bot.cpp
server node that will provide the
ball_chaser/command_robot
service. Create the script under the
src
directory of your
ball_chaser
package. It might be a bit challenging to write this script from scratch, thus I am providing you with some hints.
Attached below is a program that will continuously publish to the robot
/cmd_vel
topic. This code will drive your robot forward:
#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
//TODO: Include the ball_chaser "DriveToTarget" header file
// ROS::Publisher motor commands;
ros::Publisher motor_command_publisher;
// TODO: Create a handle_drive_request callback function that executes whenever a drive_bot service is requested
// This function should publish the requested linear x and angular velocities to the robot wheel joints
// After publishing the requested velocities, a message feedback should be returned with the requested wheel velocities
int main(int argc, char** argv)
{
// Initialize a ROS node
ros::init(argc, argv, "drive_bot");
// Create a ROS NodeHandle object
ros::NodeHandle n;
// Inform ROS master that we will be publishing a message of type geometry_msgs::Twist on the robot actuation topic with a publishing queue size of 10
motor_command_publisher = n.advertise<geometry_msgs::Twist>("/cmd_vel", 10);
// TODO: Define a drive /ball_chaser/command_robot service with a handle_drive_request callback function
// TODO: Delete the loop, move the code to the inside of the callback function and make the necessary changes to publish the requested velocities instead of constant values
while (ros::ok()) {
// Create a motor_command object of type geometry_msgs::Twist
geometry_msgs::Twist motor_command;
// Set wheel velocities, forward [0.5, 0.0]
motor_command.linear.x = 0.5;
motor_command.angular.z = 0.0;
// Publish angles to drive the robot
motor_command_publisher.publish(motor_command);
}
// TODO: Handle ROS communication events
//ros::spin();
return 0;
}
Take a look at this program and try to understand what is happening. Then, copy it to
drive_bot.cpp
, and make the necessary changes to define a
ball_chaser/command_robot
service.
Edit CMakeLists.txt
After you write the server node in C++, you’ll have to add the following dependencies:
-
Add the
add_compile_options
for C++ 11 dependency, this step is optional and depends on your code -
Add the
add_service_files
dependency which defines the DriveToTarget.srv file -
Add the
generate_messages
dependency -
Add
include_directories
dependency -
Add the
add_executable
,target_link_libraries
, andadd_dependencies
dependency for yourdrive_bot.cpp
script
Build Package
Now that you’ve included specific instructions for your
drive_bot.cpp
code in
CMakeLists.txt
file, compile it with:
$ cd /home/workspace/catkin_ws/
$ catkin_make
Test
drive_bot.cpp
To test if the service you wrote is working, first launch the robot inside your world. Then call the
/ball_chaser/command_robot
service to drive the robot forward, left, and then right.
1- Launch the robot inside your world
$ cd /home/workspace/catkin_ws/
$ source devel/setup.bash
$ roslaunch my_robot world.launch
2- Run the
drive_bot
node
$ cd /home/workspace/catkin_ws/
$ source devel/setup.bash
$ rosrun ball_chaser drive_bot
3- Request a
ball_chaser/command_robot
service
Test the service by requesting different sets of velocities from the terminal.
Open a new terminal while all the nodes are running and type:
$ cd /home/workspace/catkin_ws/
$ source devel/setup.bash
$ rosservice call /ball_chaser/command_robot "linear_x: 0.5
angular_z: 0.0" # This request should drive your robot forward
$ rosservice call /ball_chaser/command_robot "linear_x: 0.0
angular_z: 0.5" # This request should drive your robot left
$ rosservice call /ball_chaser/command_robot "linear_x: 0.0
angular_z: -0.5" # This request should drive your robot right
$ rosservice call /ball_chaser/command_robot "linear_x: 0.0
angular_z: 0.0" # This request should bring your robot to a complete stop
Launch Files
Let’s add the
drive_bot
node to a launch file. Create a
ball_chaser.launch
file under the
launch
directory of your
ball_chaser
package and then copy this code to it:
<launch>
<!-- The drive_bot node -->
<node name="drive_bot" type="drive_bot" pkg="ball_chaser" output="screen">
</node>
</launch>
This code will launch your
drive_bot
node, which is contained in the
ball_chaser
package. The server node outputs all the logs to the terminal window.
Task Description:
Follow these steps to create the
drive_bot
node :
Task Feedback:
Great job!